Image
The Strategy Pattern & SRP
Decoupling Algorithms for Maintainable, Extensible Architectures
Image
Encapsulated Behaviors
The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable at runtime.
Composition over Inheritance.
Dynamic behavior switching.
Strong Isolation of Logic.
Image
Image
Image
Defining the Strategy Pattern
Image
Image
PART I
The "God Class" Monolith
A Single Responsibility Principle (SRP) Violation
Image
Image
Image
Image
C# Code Implementation
SRP Violations
This class has many reasons to change, failing the fundamental rule of SRP:
public class
public void
string
decimal
if
"CreditCard"
/* 50 lines of Visa/Master logic */
else if
"PayPal"
/* API Handshake logic */
else if
"Crypto"
/* Blockchain validation */
Change to PayPal API breaks the file.
Adding "Apple Pay" requires editing core logic.
Testing Crypto requires mocking PayPal.
Image
Image
Image
The Single-Method Monolith
Image
Fragile Complexity
The Cost of High Coupling
In a monolithic method, logic for unrelated features is tangled together. This "spaghetti code" creates a fragile system where a change in one area causes unexpected regressions in another.
The more payment methods you add, the more difficult the class becomes to read, maintain, and unit test effectively.
Image
Image
PART II
Refactoring to Strategy
Enforcing Single Responsibility through Interfaces
Anatomy of the Pattern
The client interacts with the Context, oblivious to which ConcreteStrategy is actually executing.
Context: Maintains a reference to the Strategy.
Strategy: The common interface (IPayment).
ConcreteStrategy: Individual classes implementing unique logic (e.g., PayPalStrategy).
The Strategy UML Pattern
Image
The Strategy UML Pattern
Image
Sequence Diagram
Image
Image
Image
Image
Image
1. The Strategy Interface
A clean, single-method contract that all algorithms must follow.
2. Concrete Strategies
Now, each class has exactly one reason to change.
public interface
void
decimal
public class
public void
decimal
// PayPal API Handshake ONLY
Defining the Contract
Image
Image
public class
private
public void
public void
decimal
Decouples the Checkout flow from payment logic.
Algorithms are "plugged in" dynamically.
Easy to swap strategies mid-session.
Image
Image
Image
Context: The Runtime Switch
Image
Image
Image
Image
Card Strategy
Validation, encryption, and banking gateway integration.
PayPal Strategy
OAuth2 authentication and external redirect handshakes.
Crypto Strategy
Blockchain verification and wallet address confirmation.
Image
Image
Image
Modular Payment Models
Image
With Strategy
PaymentProcessor receives the payment strategy.
Coupling is limited to the dependencies of each payment strategy.
Each class has a single reason to change.
New processors can be added without changes to existing processors.
Modules Should Be Deep!
- Ousterhout
Image
Without Strategy
All payment models live in PaymentProcessor
High coupling: dependencies created on every provider + helper (today and all future)
Many reasons to change:
- new payment type
- API change (PayPal/gateway/crypto)
- validation/encryption rules
Hard to test: must mock unrelated systems
Image
C# Demo
Image
C# Demo
Image
C# Demo
Image
C# Demo
Image
C# Demo
Image
C# Demo
Image
Image
Architecture Comparison
1 / 20